/**
 * Copyright (C), 2020-2021 by colley.ma
 * File Name: FutureTimeAdapter.java
 * Encoding: UTF-8
 * Date: 2021年4月2日 下午2:37:59
 * History:
 */
package com.swak.frame.extension.adapter;

import java.util.Date;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import com.swak.frame.dto.base.BizScenario;
import com.swak.frame.extension.executor.ExtensionExecutor;
import com.swak.frame.extension.provider.FutureClockTimeExtPtProvider;

public class FutureClockTime implements SmartInitializingSingleton {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private ExtensionExecutor extensionExecutor;

    private FutureClockTimeExtPtProvider futureClockTimeExtPtProvider;

    public FutureClockTime(ExtensionExecutor extensionExecutor) {
        this.extensionExecutor = extensionExecutor;
    }

    public Date getClockTime(String pin) {
        if (StringUtils.isEmpty(pin)) {
            return new Date();
        }
        if (isWhiteList(pin)) {
            Date configDate = futureClockTimeExtPtProvider.getClockTime();
            if (configDate == null) {
                return new Date();
            }
            logger.warn("时间穿越成功! PIN：{}, 使用配置的时间,date:{}！!", new Object[] {pin, configDate.toString()});
            return configDate;
        }
        return new Date();
    }

    public boolean isWhiteList(String pin) {
        if (StringUtils.isEmpty(pin)) {
            return false;
        }

        Set<String> whiteList = extensionExecutor.execute(FutureClockTimeExtPtProvider.class,
            BizScenario.valueOf(FutureClockTimeExtPtProvider.FCLOCK_BIZ_ID), extension -> extension.whiteListConfig());
        // 白名单属性是否配置,未配置放行
        if (CollectionUtils.isEmpty(whiteList)) {
            return false;
        }

        boolean isMatch = whiteList.stream().anyMatch(wpin -> Objects.equals(wpin, pin));
        // 不匹配，说明该pin不在白名单中，不放行
        return isMatch;
    }

    @Override
    public void afterSingletonsInstantiated() {
        if (futureClockTimeExtPtProvider == null) {
            this.futureClockTimeExtPtProvider = extensionExecutor.locateComponent(FutureClockTimeExtPtProvider.class,
                BizScenario.valueOf(FutureClockTimeExtPtProvider.FCLOCK_BIZ_ID));
        }
    }

}
